﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="LogEntry.cs" company="DissingNelleman">
//   
// All rights reserved. </copyright>
// <summary>
//   The log entry.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ServiceLibrary.Services.Dto
{
    using System;
    using System.Runtime.Serialization;

    using ServiceLibrary.Models.Base;
    using System.Reflection;
    using System.ComponentModel;

    /// <summary>
    /// The log entry.
    /// </summary>
    [DataContract]
    public class LogEntry
    {
        #region Public Properties

        /// <summary>
        /// Gets or sets the action type.
        /// </summary>
        [DataMember]
        public Enums.LogEntryActionType ActionType { get; set; }

        /// <summary>
        /// Gets or sets the edited object id.
        /// </summary>
        [DataMember]
        public Guid EditedObjectID { get; set; }

        /// <summary>
        /// Gets or sets the editor id.
        /// </summary>
        [DataMember]
        public Guid EditorID { get; set; }

        /// <summary>
        /// Gets or sets the id.
        /// </summary>
        [DataMember]
        public Guid ID { get; set; }

        /// <summary>
        /// Gets or sets the object type.
        /// </summary>
        [DataMember]
        public Enums.LogEntryType ObjectType { get; set; }

        /// <summary>
        /// Gets or sets the text.
        /// </summary>
        [DataMember]
        public string Text { get; set; }

        /// <summary>
        /// Gets or sets the timestamp.
        /// </summary>
        [DataMember]
        public DateTime Timestamp { get; set; }

        /// <summary>
        /// Gets or sets the action type.
        /// </summary>
        [DataMember]
        public string ActionTypeName { get; set; }

        /// <summary>
        /// Gets or sets the object type.
        /// </summary>
        [DataMember]
        public string ObjectTypeName { get; set; } 

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The convert.
        /// </summary>
        /// <param name="log">
        /// The log.
        /// </param>
        /// <returns>
        /// The <see cref="LogEntry"/>.
        /// </returns>
        public static LogEntry Convert(Models.Base.LogEntry log)
        {
            if (log != null)
            {
                var dto = new LogEntry
                              {
                                  ID = log.ID, 
                                  EditorID = log.Editor.ID, 
                                  Text = log.Text, 
                                  Timestamp = log.Timestamp, 
                                  EditedObjectID = log.EditedObjectID,
                                  ObjectType = log.ObjectType,
                                  ObjectTypeName = LogEntry.GetDescription(log.ObjectType),
                                  ActionType = log.ActionType,
                                  ActionTypeName = LogEntry.GetDescription(log.ActionType)
                              };
                return dto;
            }
            
            return null;
        }

        private static string GetDescription(Enum en)
        {
            Type type = en.GetType();

            MemberInfo[] memInfo = type.GetMember(en.ToString());

            if (memInfo != null && memInfo.Length > 0)
            {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

                if (attrs != null && attrs.Length > 0)
                {
                    return ((DescriptionAttribute)attrs[0]).Description;
                }
            }

            return en.ToString();
        }

        #endregion
    }
}

namespace ServiceLibrary.Services.Queries
{
    using System.Runtime.Serialization;

    using NHibernate;

    using ServiceLibrary.Actioners.Base;
    using ServiceLibrary.Services.Results;
    using System;

    /// <summary>
    /// The log entry query.
    /// </summary>
    [DataContract]
    public class LogEntryQuery : IQuery
    {
        #region Public Methods and Operators

        /// <summary>
        /// Gets or sets the action type.
        /// </summary>
        [DataMember]
        public Enums.LogEntryActionType? ActionType { get; set; }

        /// <summary>
        /// Gets or sets the edited object id.
        /// </summary>
        [DataMember]
        public Guid? EditedObjectID { get; set; }

        /// <summary>
        /// Gets or sets the editor id.
        /// </summary>
        [DataMember]
        public Guid? EditorID { get; set; }

        /// <summary>
        /// Gets or sets the object type.
        /// </summary>
        [DataMember]
        public Enums.LogEntryType? ObjectType { get; set; }

        /// <summary>
        /// The execute.
        /// </summary>
        /// <param name="hsession">
        /// The hsession.
        /// </param>
        /// <returns>
        /// The <see cref="IResult"/>.
        /// </returns>
        public override IResult Execute(ISession hsession)
        {
            var actioner = new LogEntryActioner(hsession, null);
            return actioner.ExecuteSearchQuery(this);
        }

        #endregion
    }
}

namespace ServiceLibrary.Services.Results
{
    using System.Collections.Generic;
    using System.Runtime.Serialization;

    using ServiceLibrary.Services.Dto;

    /// <summary>
    /// The log entry result.
    /// </summary>
    [DataContract]
    public class LogEntryResult : IResult
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="LogEntryResult"/> class.
        /// </summary>
        public LogEntryResult()
        {
            this.List = new List<LogEntry>();
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets or sets the list.
        /// </summary>
        [DataMember]
        public List<LogEntry> List { get; set; }

        /// <summary>
        /// Gets or sets the total row count.
        /// </summary>
        [DataMember]
        public int TotalRowCount { get; set; }

        #endregion
    }
}